Repository navigation
A node depends on an interface or exposes one: retire Input and Output, rename the module body's inputs to deps - #398
Conversation
Input and Output were the words for the two ends of a connection, and they were ambiguous: the dataflow reading and the ports-and-adapters reading give the same two ends opposite names. The record settles the words the authoring surface already uses, deps and expose, with interface as the noun, and retires the port words. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
…tput The glossary defines Interface, Dependency and Exposed interface in place of Input, Output and Port; the domain map, layering map, authoring surface, example app, principles and domain docs use the same words. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
The one user-facing place that called a dependency an input. The shared modules, the example and the tests follow; the topology's port direction field says what in and out mean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
|
✅ Gizmo reviewed 885170a — posted 0 inline comment(s) this pass. Open findings: none Change walkthroughThis PR retires the Input/Output vocabulary across Composer in favor of dependency / exposed interface — the words the authoring surface already uses ( Terminology and docs. The glossary, guiding principles, domain map, layering map, example-app narrative, and domain docs now describe a connection as wiring a node's dependency to another node's exposed interface. "Input" survives only in its unrelated meaning — the configuration document declared as Authoring surface. Deliberately unchanged. Two internal names keep the retired word — Tests. No behavior changes. The composition, authored-graph, resource-slot, and application-topology tests now destructure |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
commit: |
…interface The error texts still called a declared dependency an input and an exposed interface an output, and the skill still said ports. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
…ond pass; a resource may carry its edge and props (#396) * docs(design): propose ingress, module input and per-stage configuration (ADR-0060 to ADR-0062) ADR-0060: public HTTP traffic reaches a service only through an ingress(), a driver on an exposed HTTP port. ADR-0061: a module declares its input as one schema, as a compute service does; the root may declare input. ADR-0062: per-stage configuration comes from providers named in the composer section; every stage has a name. Adds the Prisma Cloud ingress doc and amendment notes on the ADRs, index and glossary entries these change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): link the Prisma Cloud ingress doc to the PDP proposal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): point domain docs at ADR-0061 and ADR-0062; label ADR-0016 as amended Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): restate the stage rule as a fixed graph structure for any input ADR-0024's "the stage never appears in the authored topology" becomes what it protects: the graph's structure is the same whatever inputs Composer is given. Code may select values per stage, resolved after the graph is built with provision disabled, never structure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): make the ADR-0061 notes on core-model and module-composition accurate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): public URLs, resolve(), environments (ADR-0060 to ADR-0062 rewritten) Applies the team discussion: the node is publicUrl() with two explicit strategies on it; a per-environment or derived value is computed with resolve(deps, fn) after the graph is built; "stage" becomes "environment"; config adapters bring in outside values but no longer carry the URL story; the platform gains Public URL and Domain records. Adds the public URL domain map and scenarios as companion drafts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): link ADR-0062 to the renamed ADR-0059 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): fix a nested resolve(), scenario 9's absent key, and leftover stage wording Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): drop duplicated index annotations from the merge Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): settle the publicUrl strategy names, bare-string shorthand and local-dev warning Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): public URLs project spec and plan Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): an input reference may be passed anywhere a value is accepted; drop the DNS-label row Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): align ADR-0061's spike bullet with the amended rule Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): public URLs project in the Drive shape Spec with non-goals, place in the larger world, cross-cutting requirements, transitional-shape constraints and a verifiable project DoD; design notes for the execution decisions the ADRs don't carry; the plan cut to eight slices with owners. Module input and config adapters become a follow-on project, recorded in .drive/deferred.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): resolve() lists the environment as a dependency and receives one tuple The environment's name is no longer an extra argument to fn: it is a reference, environment.name, listed like an input or another resolved value, so new deploy-time facts add references, not parameters. fn receives the listed values as one tuple, the shape of Vue's watch and Solid's on; the useMemo analogy is dropped. The dependency list is kept because it is the only way one resolved value can be computed from another, and it gives Composer a graph to order and check for cycles. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): finish the resolve() tuple change in scenario 4 and the deferred entry Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the platform records are ServiceUrl and domain ownership Names and shape from the platform design discussion of 2026-10-27: one ServiceUrl entity for internal and external reach (named or assigned, public or private, several per service, conditions instead of a status, reconciled by the control plane over an unchanged Foundry); a domain ownership record on the workspace claiming an exact name or wildcard with today's TXT value; nothing created unless asked, with Composer declaring private URLs for called services and turning the platform's default URL off. The Drive spec and plan point D1 at the control plane's own project, projects/service-urls. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): the Alchemy resource is Prisma.ServiceUrl Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): P2 owns the post-transition lowering; design notes match the plan's owners Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): rewrite ADR-0060, 0061 and 0062 for a reader without our context Each now opens with the decision and a grounding example that builds up one idea at a time, keeps the reasoning in the present tense, and ends with the alternatives. Project language (spikes, migrations of the shipped modules), transitional states (--stage replaced, the retired destroy target, 'for now' platform behaviour) and process references are gone; the stale 'per project sharing the Domain' uniqueness rule is now platform-wide. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): fix a doubled full stop in the index Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): replace ASCII diagrams with tables and prose Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): U1 needs Alchemy's live test; C2 waits for the environment decision Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the platform record is RoutingUrl; the ownership field is domain Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the first platform step covers custom hostnames only A public URL with a named hostname becomes a RoutingUrl record; a generated URL creates nothing, because every service keeps the platform's hostname. Domain ownership is a claim, verified on conflict. A hostname is unique at registration, not at creation. Resolved values never set a node's identity. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): ownership is a claim, not a proof Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): scenario 4 follows the registration-time rule; consistent terms Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): dev takes --environment; the index matches the amended public URL decision Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the deploy CLI doc lists --environment on prisma dev Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): the endpoint as a routing URL is step two of this project Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the strategy is publicUrl.prismaBuild(); the Alchemy resource adopts existing rows Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): scenario 3 is the adoption rule's plain case; prismaBuild() lowers to a row in step two Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): adoption applies to custom hostnames too Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): a Console record is touched only to adopt it Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): one document states the whole public-URL proposal, with a reading order Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): every public-URL document in one folder Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the public-URL proposal in full sentences Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the proposal starts from an example, maps the three domains, and walks the key operations Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the proposal opens with the user's problem Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(drive): links to the moved public-URL documents resolve Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the RoutingUrl repository keeps Foundry consistent; Foundry's words throughout Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the domain map names the six conditions as the design does Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): queued retry and the Console check button in place of the cron Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): one press completes a hostname; waiting rows get the hostname without a user; scope wording Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): one press completes a hostname; waiting rows get a freed hostname without a user Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): bounded recreate; provisioning follow-up runs for the issuance timeout Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform lifecycle copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the promote diagram's requeue note matches the policy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform lifecycle copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the row records when its custom domain was created Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the issuance clock starts at creation or the latest retry Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): link the platform's consistency rule from the proposal Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): name the teams: Terminal, Portal, Metal Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the proposal links the general consistency design and both surveys Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): link the consistency overview from the proposal Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): Mermaid messages without semicolons or angle brackets Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the systems below the control plane are the data plane Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies with the observed columns Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copies Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): plan the project as four user increments Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): specify and plan slice C1, resolve() and the second pass The slice contract for resolve(): the value type, where it is accepted, the second evaluation pass that seals provision and substitutes results, the environment name's path into Load, and a resource that carries its dependency edge from construction, which the public URL node needs next. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 also resolves values inside a resource's options A public URL's url is a parameter of a resource-kind node, not a service input, so the second pass must substitute there too. The resource carries a plain-data options bag the factory records; the graph holds a resolved copy with its prototype kept. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): a deploy prints the records to publish; the platform creates the claim on verification; DNS adapter is a follow-on Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the deploy output prints the records and no Console link; refresh the platform copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the scenarios and the overview print the records, not a Console link; refresh the platform copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): refresh the platform copy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs: move the public-URLs proposal under the project folder until close-out The public design documentation under docs/design/ receives material only when a project closes and its design is final. The proposal, the domain map, the scenarios and the copies of the platform design belong to the project while it is open. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 spec pins values, resolve() and the second pass in full The slice contract after the design discussion with Will on 2026-10-29: the thing resolve() returns is a value, provided or computed, deploy-time or runtime; the public URL node is a resource that carries its edge and options from construction. Every type, signature, error message, file and test is pinned so the implementer decides nothing. The decision records for resolve(), public URLs and resources carry amendment notes, the glossary defines the term, and the project docs use it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 spec folds in the architect and principal-engineer reviews The two design reviews found four mechanisms that fail as pinned (the frozen-node copy, sealing nested modules, values inside non-plain objects, a user's thrown error reported as a Composer bug) and several names that contradict the vocabulary. The spec now pins the fixes: one plain-data predicate for the walk and the result check, one shared seal flag, a copy built from descriptors, a LoadError with cause, purity of fn, optional environment on lowering options, real value as the term for what a value stands for, and the kind-and-role reconciliation of resource and driver. Four points are recorded as pending Will. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 spec records the four settled points A resource keeps provides (a public URL provides its ingress contract); its bound producers are deps, as at provision(); its configuration is props; a computed value may not return a secret or param source. The port vocabulary question Will raised is recorded as its own decision record to be written beside the slice. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: add the Value type and resolve() A module body needs a stand-in for data that is only known per environment. Value<T> is that stand-in: opaque to the body, branded with Symbol.for so a check survives duplicated module instances, and carrying its origin under a symbol key so the body has no member to read. resolve(dependencies, fn) declares a computed value; environment.name is the one provided value. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: Load resolves every bound value in a second pass A service input binding and a service param now accept a value, and the module context hands every body environment.name. After the first pass builds and validates the graph, Load seals provision() and resolves each bound value dependency-first, once each, then substitutes the real values into the bindings. Load takes the environment's name through a new LoadOptions.environment. A value can configure a node but never shape the graph, so provision() refuses one as an id, in deps, or as a module secrets or params binding, and provision() called from inside a resolve() function fails. LoadError gains an optional cause so a user's thrown error is wrapped exactly once. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: lowering() passes the environment's name to Load LowerOptions.environment replaces the unread stage option, so the graph the stack file lowers has its values resolved for the environment being deployed. It stays optional: a hand-composed stack that binds no value needs none. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 spec records how D1 landed Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: a resource may declare slots wired at construction and carry props ResourceNode gains inputs, deps (the producers wired into those slots) and props (plain data and values). resource() and ResourceNodeBase take them and check that deps wire exactly the declared inputs, never to a value, and that props is a plain object. isPlainObject moves into value.ts so node.ts can use it without importing resolve-values.ts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: Load wires a resource's slots and resolves values in its props provision() of a resource now records its slot nodes, input and dependency edges, in ports and authored edges, and checks its wiring with the rest of the graph. serviceInputs becomes dependencySlots, over services and resources. The second pass walks each resource's props; a resource whose props held a value appears in the graph as a frozen copy that keeps its prototype and brand. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: a resource descriptor reads its slots through connectionInputs The inputs half of buildConfig becomes connectionInputs, over a service or a resource, so a resource descriptor gets the same "did not supply it" check a service gets. The provisioned-param minting loop accepts a resource consumer as well as a service. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: tests for a resource with slots wired at construction resource-slots.test.ts covers the slot node, edges, ports, authored edges, forwarded module inputs, the construction errors, the cycle check and the resolved props copy. lowering.test.ts covers a resource descriptor reading its resolved props and its producer's outputs through connectionInputs. value.test-d.ts covers the resource factory's types. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 spec records how D2 landed Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: provision(resource, { deps }) says a resource is wired at construction Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: module test asserts the new provision(resource, { deps }) text Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * core: a resource from another copy of core with no inputs, deps or props has no slots Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * cli: the environment name reaches Load in the CLI and in the generated stack files runPipeline takes the environment and passes it to Load; deploy, destroy and dev pass the one they hold. Both generated stack files render environment into LowerOptions. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * examples/env-param: serve a value computed from the environment's name The module binds a second input key, environment, to resolve() over environment.name; the server echoes it and the smoke script asserts it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 spec records how D3 landed Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(decisions): align the value amendments with the landed slice The resolve() amendment uses the glossary's words for a value and its real value. The public URL amendment says what a resource's deps hold. The index marks the resolve() and public URL amendments in the house form. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): the glossary and domain docs describe values and Load's second pass The glossary's Value entry names RealValuesOf. The core model shows resource() with inputs, deps and props, Load's options and its second pass over values, and LowerOptions with environment in place of stage. Module composition adds environment to the module context. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(guides, skill): values that differ per environment The building guide gains a section on environment.name and resolve(): where a value is accepted, why it is opaque, why provision() inside fn fails, why fn must be pure, and the errors an author can hit. The reusable-modules section lists environment among what the builder receives, and the service input section lists a value as a binding leaf. The deploying guide's environments section points at it, and the skill mirrors it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive: record the two debts the values slice leaves Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): keep C1's design reviews apart from its code reviews Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * refactor(core): name the plain-data type PlainData PlainValue read as a kind of Value, which is the reverse of what it is: the data a Value may stand for. PlainData matches the error texts and the prose. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * refactor(core): name the slot builder for what it returns dependencySlots returned graph nodes and edges, not slots, and its error called a resource a service. It is now slotNodesAndEdges(node, nodeId), and the error says Node "…" has no inputs map. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * refactor(core): name a props member ResourcePropsMember ResourceProp is any member at any depth inside props, not a property. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * refactor(core): call a binding site's partition kind, not channel The guides use "channel" for dependencies versus input. The binding site splits input, param and props, a different partition. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * refactor(core): derive the environment shapes from EnvironmentFacts A value origin's fact is now keyof EnvironmentFacts, and one mapped type, EnvironmentRealValues, gives the real-value shape that LoadOptions and resolveValues take. A second fact is now one new key. LoadOptions moves to graph-types.ts and graph.ts re-exports it, so load-module.ts no longer imports graph.ts, which imports it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * fix(core): a param binding takes a value only for a plain-data param ParamBindings accepted Value<T> for any param type, so a value standing for a Date compiled and then always failed at Load. It now accepts a value only when the param's output type is plain data, as an input binding does. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * refactor(core): connectionInputs takes the lowering context A resource descriptor called connectionInputs with five fields of the LowerContext it already holds. The exported function now takes the context; buildConfig keeps its signature and shares a private helper. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * test(core): a provisioned need on a resource slot is minted The minting loop accepts a resource consumer, but no test reached that branch. This one wires a resource slot with a provision need and checks the minted value arrives through connectionInputs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * fix(prisma-cloud): count a resource consumer's provisioned edge Core mints a value for a resource slot that carries a provision need, but provisionedEdges skipped every consumer that was not a service, so the producer would never accept the minted key. The scan now matches core's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * test(core): group the second pass's tests by what they check The resource-props tests move beside the other second-pass tests, since props are a binding site, not a slot. The refusals of a value as an id, a deps entry, a secrets or a params binding run in the first pass, so they get their own describe block. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * fix(core): seal provision when Load fails before its second pass If the first pass, the wiring check or the cycle check threw, that Load's provision stayed open, and a leaked closure could add nodes to a dead Load without an error. The seal now runs in a finally. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * test(core): pin the param, prop and whole-input binding texts Only the input-key text was asserted. The param, resource-prop and whole input binding texts now each have an exact-message case. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * fix(example): the env-param smoke run waits out an older revision An older revision with the same greeting and no environment field could still be serving right after a deploy, and the smoke run failed at once. It now keeps polling on an environment mismatch and prints the FAIL line only when the deadline passes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(core): name every use of deps on a resource's deps field The comment named only ModuleNode.deps as the clash. module()'s boundary deps and compute()'s deps declare slots too, while provision()'s and resource()'s deps bind producers. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): a resource class must not use #private fields The rule lived only in a doc comment on ResourceNodeBase. It is part of the extension contract, so the core model now states it beside the factories. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(glossary): define a Resource by its lifecycle, and add Driver The Resource entry led with "a dependency defined by its state", which a public URL contradicts. It now leads with the lifecycle test its second paragraph already states, and says "dependency slots" instead of "Inputs". A short Driver entry defines the role the Resource entry names. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(guides, skill): keep an environment's case until it is destroyed Destroying an environment runs every resolve() function for it. Removing its case from a lookup first makes destroy fail at Load and leaves its resources up, so the guide and the skill say to keep the case until destroy finishes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 spec pins a resource that exposes nothing, and records the fix round Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * feat(core): a resource may expose nothing resource() and ResourceNodeBase take either provides or type. A resource built with type alone has no $out port, and provision() returns only its id. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): a resource may expose nothing Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * style(core): format the resource-slots tests Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * fix(example): the env-param smoke run finds the app by its address Since every platform name is the node's address, the echo app is named env-param-example.echo, not echo. The smoke script looked for the old name and found nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 manual QA record Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * drive(public-urls): C1 QA record notes the teardown Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * fix(core, prisma-cloud): one guard for a resource node with no inputs A resource node built by another installed copy of core may lack inputs. Load already treated that as no slots; the minting loop in lowering and the target's provisioned-edges walk dereferenced inputs unguarded and would have thrown. slotsOf moves to node.ts and all three use it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * A node depends on an interface or exposes one: retire Input and Output, rename the module body's inputs to deps (#398) * docs(decisions): a node depends on an interface or exposes one Input and Output were the words for the two ends of a connection, and they were ambiguous: the dataflow reading and the ports-and-adapters reading give the same two ends opposite names. The record settles the words the authoring surface already uses, deps and expose, with interface as the noun, and retires the port words. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(design): say dependency and exposed interface, never Input or Output The glossary defines Interface, Dependency and Exposed interface in place of Input, Output and Port; the domain map, layering map, authoring surface, example app, principles and domain docs use the same words. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * feat(core): a module body receives its dependencies as deps, not inputs The one user-facing place that called a dependency an input. The shared modules, the example and the tests follow; the topology's port direction field says what in and out mean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs(guides, skill): the module builder's deps, and the upgrade note Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * docs, core: the Load errors and the skill say dependency and exposed interface The error texts still called a declared dependency an input and an exposed interface an output, and the skill still said ports. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * test(cron): assert the Load error's new wording Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> * test(core): a test title says dependency, not input Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
At a glance
A module body receives its dependencies as
deps, the same word the boundary declares them with:And the design documents describe the same thing in the same words. The glossary, before and after:
What this PR changes
ModuleContext.inputsis renameddeps. The shared modules, the examples, the tests, the guide and the agent skill follow, with an upgrade note in the guide.directionfield keepsinandout, now documented as the dependency end and the exposed end.Why the words were ambiguous
Take a service
webthat offers an HTTP API and needs a database. Composer's documents named the two ends by dataflow: the API is an output, because other nodes callwebthrough it, and the database is an input, becausewebcalls it. Ports and adapters, the architecture most readers bring, names the same two ends the other way round: the API is an input port, because calls come intowebthrough it, and the database is an output port, because calls go out through it.Both are consistent. Every end has both aspects, who provides it and which way calls flow, and the two traditions weigh them differently. So a reader from either tradition read half the sentences in the glossary backwards. The design discussion behind this change went through exactly that, sentence by sentence, until it was clear the words were the problem rather than either reader.
The words that name the relationship
Whether a node depends on an interface or exposes one is a fact about the node, not a direction the reader has to pick. The authoring surface already said it:
depsandexpose. The record makes those the vocabulary:Contract, which keeps its name. An interface in Composer's terms is what ports and adapters calls a port; that analogy appears once, in the glossary, and "port" is not otherwise used, because Composer also has HTTP and TCP ports.deps.expose; a resource exposes the one interface itprovides, and a node may expose nothing."Input" keeps its other meaning, the configuration document a service or module declares as
input. That is not an end of a connection, and the glossary says so once.The one user-facing rename
The module body's
inputswas the only authoring-surface word that called a dependency an input. It is nowdeps, so the body reads like the boundary it forwards:({ deps, provision }) => provision(svc, { deps: { db: deps.db } }). The guide's module section carries the upgrade note. Two internal names keep the old word,ServiceNode.inputsandInputRef; renaming them reaches into the Prisma Cloud extension and the local target, so they are recorded as debt in.drive/deferred.md.The topology's wire field
The application topology sends each end's
directionasinoroutto the platform, and the Console draws them. The field is not renamed: it belongs to the Portal team's API, and its meaning is unambiguous once defined.inis a dependency,outis an exposed interface, and the type's doc comment now says so.Tests
No behaviour changes. The rename is covered by the existing module-composition, authored-graph, resource-slot and application-topology tests, which now destructure
deps;pnpm typecheckacross all 80 packages proves no caller was missed, and the fullpnpm testsuite passes. The website content test proves every guide link still resolves, and the skill packaging check proves the skill is still the one that ships.Alternatives considered
ctx.inputsanyway, flips the meaning of a public API field, and moves every end in the Console to the other side of its card, for words that stay ambiguous to the next reader.depsandexpose, and "provider" already means an Alchemy provider here.exposetoprovidesso services matchresource({ provides }). A user-facing rename for consistency between a keyword and a verb the prose no longer leans on; left for another day.Agent: hermione-26
🤖 Generated with Claude Code